package study.springboot.starter.redis.template;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.time.Duration;
import java.util.List;

public class RedisXClient {

    private RedisTemplate<String, Object> redisTemplate;

    public RedisXClient(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 序列化
     */
    public RedisXClient useJson() {
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);
        return this;
    }

    public RedisXClient useByte() {
        ByteRedisSerializer serializer = new ByteRedisSerializer();
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);
        return this;
    }


    /**
     * 通用操作
     */
    public Boolean expire(String key, Duration timeout) {
        boolean isOK;
        try {
            isOK = redisTemplate.expire(key, timeout);
        } catch (Exception ex) {
            throw new RuntimeException("[] expire error!", ex);
        }
        return isOK;
    }

    public Long delete(List<String> keys) {
        Long count;
        try {
            count = redisTemplate.delete(keys);
        } catch (Exception ex) {
            throw new RuntimeException("[] delete error!", ex);
        }
        return count;
    }

    /**
     * String类型
     */
    public <V> void set(String key, V value) {
        try {
            redisTemplate.opsForValue().set(key, value);
        } catch (Exception ex) {
            throw new RuntimeException("[String] set error!", ex);
        }
    }

    public <V> boolean setIfAbsent(String key, V value) {
        boolean isOk;
        try {
            isOk = redisTemplate.opsForValue().setIfAbsent(key, value);
        } catch (Exception ex) {
            throw new RuntimeException("[String] setIfAbsent error!", ex);
        }
        return isOk;
    }

    public <V> boolean setIfPresent(String key, V value) {
        boolean isOk;
        try {
            isOk = redisTemplate.opsForValue().setIfPresent(key, value);
        } catch (Exception ex) {
            throw new RuntimeException("[String] setIfPresent error!", ex);
        }
        return isOk;
    }

    public <V> V get(String key) {
        V value;
        try {
            value = (V) redisTemplate.opsForValue().get(key);
        } catch (Exception ex) {
            throw new RuntimeException("[String] get error!", ex);
        }
        return value;
    }

    public Long incr(String key) {
        Long value;
        try {
            value = redisTemplate.opsForValue().increment(key);
        } catch (Exception ex) {
            throw new RuntimeException("[String] incr error!", ex);
        }
        return value;
    }

    public Long decr(String key) {
        Long value;
        try {
            value = redisTemplate.opsForValue().decrement(key);
        } catch (Exception ex) {
            throw new RuntimeException("[String] decr error!", ex);
        }
        return value;
    }
}
